﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Windows.Input;
using System.Xml.Serialization;
using UIConfigTool.Models.CDS;
using UIConfigTool.Models.Loadport;
using UIConfigTool.Models.PM;

namespace UIConfigTool.ViewModel
{
    public class RootNode : INotifyPropertyChanged
    {
        [XmlAttribute]
        public string Id { get; set; } = "RootNode";
        [XmlIgnore]
        public ObservableCollection<DeviceNode> ChildNode { get; set; } = new ObservableCollection<DeviceNode>();

        [Browsable(false)]
        [XmlArray("CDSDevices")]
        [XmlArrayItem("CDSDevice")]
        public List<CDSDevice> CDSDevices { get; set; } = new List<CDSDevice>();
        [Browsable(false)]
        [XmlArray("PMDevices")]
        [XmlArrayItem("PMDevice")]
        public List<PMDevice> PMDevices { get; set; } = new List<PMDevice>();
        [Browsable(false)]
        [XmlArray("LoadportDevices")]
        [XmlArrayItem("LoadportDevice")]
        public List<LoadportDevice> LoadportDevices { get; set; } = new List<LoadportDevice>();

        [XmlIgnore]
        public ICommand AddCDSCommand { get; private set; }
        [XmlIgnore]
        public ICommand AddLoadportCommand { get; private set; }
        [XmlIgnore]
        public ICommand AddPMCommand { get; private set; }


        public RootNode()
        {
            // 初始化命令
            AddCDSCommand = new RelayCommand<RootNode>(AddCDS);
            AddLoadportCommand = new RelayCommand<RootNode>(AddLoadport);
            AddPMCommand = new RelayCommand<RootNode>(AddPM);
            ChildNode.CollectionChanged += ChildNode_CollectionChanged;

        }
        void ChildNode_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    foreach (var item in e.NewItems)
                    {
                        if (item is CDSDevice cDS)
                        {
                            CDSDevices.Add(cDS);
                        }
                        else if (item is PMDevice pm)
                        {
                            PMDevices.Add(pm);
                        }
                        else if (item is LoadportDevice lp)
                        {
                            LoadportDevices.Add(lp);
                        }
                    }
                    break;

                case NotifyCollectionChangedAction.Remove:
                    Console.WriteLine("移除了元素:");
                    foreach (var item in e.OldItems)
                    {
                        if (item is CDSDevice cDS)
                        {
                            CDSDevices.Remove(cDS);
                        }
                        else if (item is PMDevice pm)
                        {
                            PMDevices.Remove(pm);
                        }
                        else if (item is LoadportDevice lp)
                        {
                            LoadportDevices.Remove(lp);
                        }
                    }
                    break;

                case NotifyCollectionChangedAction.Replace:
                    Console.WriteLine("替换了元素:");
                    break;

                case NotifyCollectionChangedAction.Move:
                    Console.WriteLine("移动了元素");
                    break;

                case NotifyCollectionChangedAction.Reset:
                    Console.WriteLine("集合已清空");
                    break;
            }
        }
        public void AddCDS(RootNode rootNode)
        {
            CDSDevice cdsdevice = new CDSDevice();
            rootNode.ChildNode.Add(cdsdevice);
        }
        public void AddLoadport(RootNode rootNode)
        {
            var loadport = new LoadportDevice();
            rootNode.ChildNode.Add(loadport);
        }
        public void AddPM(RootNode rootNode)
        {
            var pmdevice = new PMDevice();
            rootNode.ChildNode.Add(pmdevice);
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    [XmlInclude(typeof(CDSDevice))]
    [XmlInclude(typeof(LoadportDevice))]
    [XmlInclude(typeof(PMDevice))]
    public class DeviceNode : INotifyPropertyChanged
    {
        public DeviceNode() { }
        private string id;

        [XmlAttribute("Id")]
        public string Id
        {
            get { return id; }
            set
            {
                if (id != value)
                {
                    id = value;
                    OnPropertyChanged(nameof(Id));
                }
            }
        }
        [Browsable(false)]
        [XmlIgnore]
        public virtual ObservableCollection<DeviceBase> ChildNode { get; } = new ObservableCollection<DeviceBase>();

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
